package com.tl.juc.c3;

import cn.hutool.json.JSONUtil;

import java.util.concurrent.atomic.*;
import java.util.function.LongBinaryOperator;

public class C5_Atomic {
    public static void main(String[] args) {
        // ai();
        // aia();
        // ar();
        // au();
        ia();
    }

    // AtomicIntegerArray
    public static void aia(){
        int [] value = new int[]{1,2};

        AtomicIntegerArray aia = new AtomicIntegerArray(value);

        aia.getAndSet(0,3);
        System.out.println(aia.get(0));
        System.out.println(value[0]);

        aia.compareAndSet(1,2,5);
        System.out.println(aia.get(1));
    }

    // AtomicInteger
    public static void ai(){
        // 获取值
        AtomicInteger ai = new AtomicInteger(1);
        System.out.println(ai.get());
        // 获取值并且增加
        System.out.println(ai.addAndGet(5));
        // 比较并且设置 1.预期值 2.新值 会跟预期值相比较，如果相同设置新值，返回true
        System.out.println(ai.compareAndSet(ai.get(),10));
        System.out.println(ai.get());
        // 获取并且递增
        System.out.println(ai.getAndIncrement());
        System.out.println(ai.get());
        // 递增并且获取
        System.out.println(ai.incrementAndGet());
        System.out.println(ai.get());

        // 懒设置，不会保证可见性
        ai.lazySet(8);
        System.out.println(ai.get());
        // 先获取在设值
        System.out.println(ai.getAndSet(5));
        System.out.println(ai.get());
    }

    // AtomicReference
    public static void ar() {
        User user = new User("xushu",20);
        AtomicReference<User> atomicReference = new AtomicReference<>(user);
        System.out.println(atomicReference.get().toString());

        User updateUser = new User("zhuge",21);
        atomicReference.compareAndSet(user,updateUser);
        System.out.println(atomicReference.get().toString());
    }

    // AtomicIntegerFieldUpdater
    public static void au() {
        AtomicIntegerFieldUpdater<User> a =  AtomicIntegerFieldUpdater.newUpdater(User.class,"age");

        User xushu = new User("xushu", 10);
        System.out.println(a.getAndIncrement(xushu));
        System.out.println(a.get(xushu));
    }

    public static void ia() {
        // 无参构造函数，从0开始
        LongAdder longAdder = new LongAdder();
        longAdder.add(5);
        longAdder.increment();
        longAdder.increment();
        System.out.println(longAdder.longValue());

        LongAccumulator longAccumulator = new LongAccumulator(new LongBinaryOperator() {
            @Override
            public long applyAsLong(long left, long right) {
                return left - right;
            }
        },1000);
        while (true){
            if (longAccumulator.get()<10){
                break;
            }
            longAccumulator.accumulate(7);
        }
        System.out.println(longAccumulator.get());
    }
    static class User {
        private String name;
        public volatile int age;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        @Override
        public String toString() {
            return "name='" + name + ", age=" + age;
        }
    }
}
